#include "mainwindow.h"
#include "ui_mainwindow.h"

void MainWindow::Port_F210_Port_Init()
{
    //
    PortSerial = new QSerialPort();
    SerialThread = new QThread();
    connect(SerialThread, &QThread::finished, this,&QObject::deleteLater);
    SerialThread->start();
    PortSerial->moveToThread(SerialThread);
    connect(PortSerial, &QSerialPort::readyRead, this, &MainWindow::Port_Serial_Read_clicked);

    //
    ComThread_disp_f210 = new comthread_f210(this);
    connect(ComThread_disp_f210, &QThread::finished, this,&QObject::deleteLater);
    ComThread_disp_f210->start();
    connect(ComThread_disp_f210,SIGNAL(UpdateSerialData(QByteArray)),this,SLOT(disp_f210_data_receive(QByteArray)));

    SyncTimer = new QTimer;
    connect(SyncTimer,&QTimer::timeout,this,&MainWindow::Port_F210_Sync_Timer);//同步
    SyncTimer->stop();
    RecvTimer = new QTimer;
    connect(RecvTimer,&QTimer::timeout,this,&MainWindow::Port_Serial_Read_Data);//
    RecvTimer->stop();
    WaitTimer = new QTimer(this);
    connect(WaitTimer,&QTimer::timeout,this,&MainWindow::Port_F210_Once_Timer);
    WaitTimer->setSingleShot(true);
}

// F210原彩修复-写盖板码
bool MainWindow::Mtsn_Write_to_Mcu(int SendCmd)
{
    QString MtsnStr = ui->te_mtsn->toPlainText();
    if(MtsnStr.isEmpty())
    {
        if(LangureStu == 1)
        {
            LangureStr = "MtSN burning Failed, Burn MtSN cannot be empty!";
        }
        else
        {
            LangureStr = "盖板码写入失败，写入盖板码不能为空!";
        }
		InsertText(ui->te_prin, LangureStr, NORMAL_FONT_SIZE, APP_FONT_COLOR_WARNNING);
        return false;
    }
    else if(44 != MtsnStr.size())
    {
        if(LangureStu == 1)
        {
            LangureStr = tr("MtSN burning Failed, MtSN length[%1] is incorrect, Pleasere-enter it!").arg(MtsnStr.size());
        }
        else
        {
            LangureStr = QString("盖板码写入失败，盖板码长度[%1]有误，请重新输入!").arg(MtsnStr.size());
        }
        InsertText(ui->te_prin, LangureStr, NORMAL_FONT_SIZE, APP_FONT_COLOR_WARNNING);
        return false;
    }

    //发送写入盖板码请求
    QByteArray LineStr;
    LineStr.clear();
    LineStr = MtsnStr.toLatin1();
	if(SEND_BURN_MTSN_DEV == SendCmd)
	{
		LangureStr_Init_BurningCode_DevData(ui->te_prin);
	}
	else
	{
		LangureStr_Init_BurningCode(ui->te_prin);
	}

    Wait_TimeOut_to_Send_Three_Time(LineStr,PORT_STU_BURN_MTSN,SendCmd);
    if(PORT_STU_BURN_MTSN != PortStu)
    {
        if(SEND_BURN_MTSN_DEV == SendCmd)
        {
            if(PORT_STU_BUSY == PortStu)
            {
                LangureStr_Init_BurnCode_DevData_Failed_Busy(ui->te_prin);
            }
            else if(PORT_STU_TIMEOUT == PortStu)
            {
                LangureStr_Init_BurnCode_DevData_Failed_Time(ui->te_prin);
            }
            else
            {
                LangureStr_Init_BurnCode_DevData_Failed(ui->te_prin);
            }
        }
        else
        {
            if(PORT_STU_BUSY == PortStu)
            {
                LangureStr_Init_BurnCode_Failed_Busy(ui->te_prin);
            }
            else if(PORT_STU_TIMEOUT == PortStu)
            {
                LangureStr_Init_BurnCode_Failed_Time(ui->te_prin);
            }
            else
            {
                LangureStr_Init_BurnCode_Failed(ui->te_prin);
            }
        }
        return false;
    }

    //等待mcu回应
#if 0   //20230209_1844 对F210进行改进，注释掉此语句
    if(1 == PortVer)
    {
        if(!Wait_TimeOut_to_Wait_Mcu_Answer())
        {
            if(PORT_STU_BUSY == PortStu)
            {
                if(LangureStu == 1)
                {
                    LangureStr = "MtSN burning failed, The device is busy, please operate later!";
                }
                else
                {
                    LangureStr = "盖板码写入失败，设备繁忙，请稍后操作!";
                }
                InsertText(ui->te_prin, LangureStr, NORMAL_FONT_SIZE, APP_FONT_COLOR_WARNNING);
            }
            else if(PORT_STU_TIMEOUT == PortStu)
            {
                if(LangureStu == 1)
                {
                    LangureStr = "MtSN burning failed, The device timed out. Please check the device connection status and try again!";
                }
                else
                {
                    LangureStr = "盖板码写入失败，设备超时，请检查设备连接状态后重试!";
                }
                InsertText(ui->te_prin, LangureStr, NORMAL_FONT_SIZE, APP_FONT_COLOR_WARNNING);
            }
            else
            {
                if(LangureStu == 1)
                {
                    LangureStr = "MtSN burning failed!";
                }
                else
                {
                    LangureStr = "盖板码写入失败!";
                }
                InsertText(ui->te_prin, LangureStr, NORMAL_FONT_SIZE, APP_FONT_COLOR_FAILED);
            }
            return false;
        }
    }
    else
    {
        Wait_Time_to_Wait_Mcu(TIME_MCU_TIME_OUT);
    }
#endif
    if(0 == PortVer)    // 兼容旧设备
    {
        Wait_Time_to_Wait_Mcu(TIME_MCU_TIME_OUT);
    }
    else    //20230209_1845 在写入盖板码时需要等待设备写入，因此加入else语句
    {
        if(SEND_BURN_MTSN_DEV != SendCmd)
        {
            if(!Wait_TimeOut_to_Wait_Mcu_Answer())
            {
                if(PORT_STU_BUSY == PortStu)
                {
                    LangureStr_Init_BurnCode_DevData_Failed_Busy(ui->te_prin);
                }
                else if(PORT_STU_TIMEOUT == PortStu)
                {
                    LangureStr_Init_BurnCode_Failed_Time(ui->te_prin);
                }
                else
                {
                    LangureStr_Init_BurnCode_Failed(ui->te_prin);
                }
                return false;
            }
        }
    }

    if(SEND_BURN_MTSN_DEV == SendCmd && PORT_STU_NULL != PortStu)
    {
        //替换底层
        QString DevFileName = FilePath + "/";
        switch (ModelStu) {
        case Model_8:
        {
            DevFileName += ROM_FILE_NAME_I8;
            break;
        }
        case Model_8P:
        {
            DevFileName += ROM_FILE_NAME_I8P;
            break;
        }
        case Model_8P_a:
        {
            DevFileName += ROM_FILE_NAME_I8P_A;
            break;
        }
        case Model_X:
        {
            DevFileName += ROM_FILE_NAME_IX;
            break;
        }
        case Model_XR:
        {
            DevFileName += ROM_FILE_NAME_IXR;
            break;
        }
        case Model_XSMax:
        {
            DevFileName += ROM_FILE_NAME_IXSMAX;
            break;
        }
        case Model_11:
        {
            DevFileName += ROM_FILE_NAME_I11;
            break;
        }
        case Model_11P:
        {
            DevFileName += ROM_FILE_NAME_I11P;
            break;
        }
        case Model_12:
        case Model_12PM:
        {
            DevFileName += ROM_FILE_NAME_I12;
            break;
        }
        case Model_13:
        {
            DevFileName += ROM_FILE_NAME_I13;
            break;
        }
		case Model_16:
        case Model_15:
        case Model_14:
        {
            DevFileName += ROM_FILE_NAME_I14;
            break;
        }
        case Model_13P:
        {
            DevFileName += ROM_FILE_NAME_I13Pro;
            break;
        }
		case Model_16P:
        case Model_15P:
        case Model_14P:
        {
            DevFileName += ROM_FILE_NAME_I14Pro;
            break;
        }
        }
        QFile DevFile(DevFileName);
        bool exist = QFile::exists(DevFileName);
        if(!exist || 16384 != DevFile.size())
        {
            if(LangureStu == 1)
            {
                LangureStr = "MtSN burning Failed, Corrupt underlying file!";
            }
            else
            {
                LangureStr = "盖板码写入失败，底层文件损坏!";
            }
            InsertText(ui->te_prin, LangureStr, NORMAL_FONT_SIZE, APP_FONT_COLOR_FAILED);
            return false;
        }
        if(!DevFile.open(QIODevice::ReadOnly))
        {
            if(LangureStu == 1)
            {
                LangureStr = "MtSN burning Failed, Failed to open the underlying file!";
            }
            else
            {
                LangureStr = "盖板码写入失败，底层文件打开失败!";
            }
            InsertText(ui->te_prin, LangureStr, NORMAL_FONT_SIZE, APP_FONT_COLOR_FAILED);
            return false;
        }

        char LineBuff[512];
        qint64 Length;
        int BurnCnt = 0;
        int DevSize = DevFile.size();
        int FileSize = 0;
        PageCnt = 0;
        while(!DevFile.atEnd()){
            if(DevSize - FileSize > 512)
            {
                Length = DevFile.read(LineBuff, 512);
            }
            else
            {
                Length = DevSize - FileSize;
                Length = DevFile.read(LineBuff, Length);
            }
            QByteArray BurnBuff;
            BurnBuff.clear();
            for(int i=0;i<Length;i++)
            {
                BurnBuff.append(LineBuff[i]);
            }
            if(0 != Length)
            {
                Wait_TimeOut_to_Send_Three_Time(BurnBuff,PORT_STU_BURN,SEND_BURN_DATA);

                if(PORT_STU_BURN != PortStu)
                {
                    if(PORT_STU_BUSY == PortStu)
                    {
                        LangureStr_Init_BurnCode_DevData_Failed_Busy(ui->te_prin);
                    }
                    else if(PORT_STU_TIMEOUT == PortStu)
                    {
                        LangureStr_Init_BurnCode_DevData_Failed_Time(ui->te_prin);
                    }
                    else
                    {
                        LangureStr_Init_BurnCode_DevData_Failed(ui->te_prin);
                    }
                    DevFile.close();
                    ui->progressBar->setValue(0);
                    return false;
                }
                BurnCnt++;
                FileSize += Length;
                ui->progressBar->setValue((int)(1+98*BurnCnt/32));
                if(32 == BurnCnt)
                {
                    break;
                }
            }
        }
        DevFile.close();

        LastPortStu = PORT_STU_FREE;
        PortStu = PORT_STU_FREE;

        //等待mcu回应
        if(1 == PortVer)
        {
            if(!Wait_TimeOut_to_Wait_Mcu_Answer())
            {
                if(PORT_STU_BUSY == PortStu)
                {
                    LangureStr_Init_BurnCode_DevData_Failed_Busy(ui->te_prin);
                }
                else if(PORT_STU_TIMEOUT == PortStu)
                {
                    LangureStr_Init_BurnCode_DevData_Failed_Time(ui->te_prin);
                }
                else
                {
                    LangureStr_Init_BurnCode_DevData_Failed(ui->te_prin);
                }
                return false;
            }
        }
        else
        {
            Wait_Time_to_Wait_Mcu(TIME_MCU_TIME_OUT);
        }
    }

    ui->progressBar->setValue(100);
    if(PORT_STU_ERROR == PortStu)
    {
        if(SEND_BURN_MTSN_DEV == SendCmd)
        {
            LangureStr_Init_BurnCode_DevData_Failed(ui->te_prin);
        }
        else
        {
            LangureStr_Init_BurnCode_Failed(ui->te_prin);
        }
        return false;
    }

    return true;
}
// F210原彩修复-读数据
bool MainWindow::Read_Data_Form_Mcu()
{
    hexEdit->clear();

    QString SaveFileName;
    ReadFileName = ui->te_file_write->toPlainText();
    if(!App_Check_Legal_FilePath(ReadFileName, 1))
    {
        InsertText(ui->te_prin, LangureStr, NORMAL_FONT_SIZE, APP_FONT_COLOR_WARNNING);
        return false;
    }
    App_Write_FilePath_CfgFile("OpenDir/Dir", ReadFileName);

    QString BakReadFileName = ReadFileName + ".bak";
    QFile BakReadFile(BakReadFileName);
    if(!BakReadFile.open(QIODevice::WriteOnly | QIODevice::Truncate))
    {
        LangureStr_Init_FileOpenFail(ui->te_prin);
        return false;
    }

    ui->progressBar->setValue(0);
    //发送读取请求
    QByteArray LineStr;
    LineStr.clear();
    RecvData.clear();
    LastPortStu = PORT_STU_READ;
    PortStu = PORT_STU_WAIT;

    Wait_TimeOut_to_Send_Three_Time(LineStr, PORT_STU_READ, SEND_READ_REQ);

    //读取数据
    int ReadCnt = 0;
    while(1)
    {
        if(PORT_STU_READ != PortStu)
        {
            if(PORT_STU_BUSY == PortStu)
            {
                if(LangureStu == 1)
                {
                    LangureStr = "Data read failed, The device is busy, please operate later!";
                }
                else
                {
                    LangureStr = "数据读取失败，设备繁忙，请稍后操作!";
                }
                InsertText(ui->te_prin, LangureStr, NORMAL_FONT_SIZE, APP_FONT_COLOR_WARNNING);
            }
            else if(PORT_STU_TIMEOUT == PortStu)
            {
                if(LangureStu == 1)
                {
                    LangureStr = "Data read failed, The device timed out. Please check the device connection status and try again!";
                }
                else
                {
                    LangureStr = "数据读取失败，设备超时，请检查设备连接状态后重试!";
                }
                InsertText(ui->te_prin, LangureStr, NORMAL_FONT_SIZE, APP_FONT_COLOR_WARNNING);
            }
            else
            {
                if(LangureStu == 1)
                {
                    LangureStr = "Data read failed!";
                }
                else
                {
                    LangureStr = "数据读取失败!";
                }
                InsertText(ui->te_prin, LangureStr, NORMAL_FONT_SIZE, APP_FONT_COLOR_FAILED);
            }
            BakReadFile.close();
            BakReadFile.remove();
            ui->progressBar->setValue(0);
            return false;
        }
        if(PORT_STU_RDOK == PortStu)
        {
            break;
        }
        BakReadFile.write(RecvData, RecvSize);
        hexEdit->append(RecvData);
        ReadCnt++;
        ui->progressBar->setValue((int)(99*ReadCnt/32));
        // 16k/512=32
        if(32 == ReadCnt)
        {
            break;
        }
        RecvData.clear();
        RecvSize = 0;

        //同步帧
        Wait_TimeOut_to_Send_Three_Time(LineStr, PORT_STU_READ, SEND_DATA_SYNC);
    }
    BakReadFile.close();

    bool exist = QFile::exists(ReadFileName);
    if(exist)
    {
        QFile::remove(ReadFileName);
    }
    exist = BakReadFile.rename(ReadFileName);

    LastPortStu = PORT_STU_FREE;
    PortStu = PORT_STU_FREE;

    return true;
}
// F210原彩修复-写数据
bool MainWindow::Burn_Data_to_Mcu()
{
    BurnFileName = ui->te_file_write->toPlainText();
#if 0
    if(BurnFileName.isEmpty())
    {
        if(LangureStu == 1)
        {
            LangureStr = "Data write failed, Write file cannot be empty!";
        }
        else
        {
            LangureStr = "数据写入失败，写入文件不能为空!";
        }
        InsertText(ui->te_prin, LangureStr, NORMAL_FONT_SIZE, APP_FONT_COLOR_WARNNING);
        return false;
    }
#else
    if(!App_Check_Legal_FilePath(BurnFileName, 0))
    {
        InsertText(ui->te_prin, LangureStr, NORMAL_FONT_SIZE, APP_FONT_COLOR_WARNNING);
        return false;
    }
    App_Write_FilePath_CfgFile("OpenDir/Dir", BurnFileName);
#endif

    ui->progressBar->setValue(0);

    QFile BurnFile(BurnFileName);
    if(BurnFile.size() != 16384)
    {
        if(LangureStu == 1)
        {
            LangureStr = "Data write failed, Write file size must be 16kb!";
        }
        else
        {
            LangureStr = "数据写入失败，写入文件大小必须为16KB!";
        }
         InsertText(ui->te_prin, LangureStr, NORMAL_FONT_SIZE, APP_FONT_COLOR_WARNNING);
        return false;
    }
    if(!BurnFile.open(QIODevice::ReadOnly))
    {
        LangureStr_Init_FileOpenFail(ui->te_prin);
        return false;
    }

    char LineBuff[512];
    qint64 Length;
    int BurnCnt = 0;
    PageCnt = 0;
    while(!BurnFile.atEnd()){
        Length = BurnFile.read(LineBuff, 512);
        QByteArray BurnBuff;
        BurnBuff.clear();
        for(int i=0;i<Length;i++)
        {
            BurnBuff.append(LineBuff[i]);
        }
        if(0 != Length)
        {
            Wait_TimeOut_to_Send_Three_Time(BurnBuff, PORT_STU_BURN, SEND_BURN_DATA);
            if(PORT_STU_BURN != PortStu)
            {
                if(PORT_STU_BUSY == PortStu)
                {
                    if(LangureStu == 1)
                    {
                        LangureStr = "Data write failed, The device is busy, please operate later!";
                    }
                    else
                    {
                        LangureStr = "数据写入失败，设备繁忙，请稍后操作!";
                    }
                    InsertText(ui->te_prin, LangureStr, NORMAL_FONT_SIZE, APP_FONT_COLOR_WARNNING);
                }
                else if(PORT_STU_TIMEOUT == PortStu)
                {
                    if(LangureStu == 1)
                    {
                        LangureStr = "Data write failed, The device timed out. Please check the device connection status and try again!";
                    }
                    else
                    {
                        LangureStr = "数据写入失败，设备超时，请检查设备连接状态后重试!";
                    }
                    InsertText(ui->te_prin, LangureStr, NORMAL_FONT_SIZE, APP_FONT_COLOR_WARNNING);
                }
                else
                {
                    if(LangureStu == 1)
                    {
                        LangureStr = "Data write failed!";
                    }
                    else
                    {
                        LangureStr = "数据写入失败!";
                    }
                    InsertText(ui->te_prin, LangureStr, NORMAL_FONT_SIZE, APP_FONT_COLOR_FAILED);
                }
                BurnFile.close();
                ui->progressBar->setValue(0);
                return false;
            }
            BurnCnt++;
            ui->progressBar->setValue((int)(99*BurnCnt/32));
            if(32 == BurnCnt)
            {
                break;
            }
        }
    }
    BurnFile.close();

    //等待mcu回应
    if(1 == PortVer)
    {
        if(!Wait_TimeOut_to_Wait_Mcu_Answer())
        {
            if(PORT_STU_TIMEOUT == PortStu)
            {
                if(LangureStu == 1)
                {
                    LangureStr = "Data write failed, The device timed out. Please check the device connection status and try again!";
                }
                else
                {
                    LangureStr = "数据写入失败，设备超时，请检查设备连接状态后重试!";
                }
                InsertText(ui->te_prin, LangureStr, NORMAL_FONT_SIZE, APP_FONT_COLOR_WARNNING);
            }
            else
            {
                if(LangureStu == 1)
                {
                    LangureStr = "Data write failed!";
                }
                else
                {
                    LangureStr = "数据写入失败!";
                }
                InsertText(ui->te_prin, LangureStr, NORMAL_FONT_SIZE, APP_FONT_COLOR_FAILED);
            }
            return false;
        }
    }
    else
    {
        Wait_Time_to_Wait_Mcu(TIME_MCU_TIME_OUT);
    }

    ui->progressBar->setValue(100);

    LastPortStu = PORT_STU_FREE;
    PortStu = PORT_STU_FREE;

    return true;
}

// F210电池修复-读数据
bool MainWindow::Read_Bat_Data_Form_F210()
{
	// 发送读取电池数据包
    QByteArray LineStr;
    LineStr.clear();
    LastPortStu = PORT_STU_READ;
    PortStu = PORT_STU_WAIT;
    Wait_TimeOut_to_Send_Three_Time(LineStr, PORT_STU_READ, SEND_READ_DATA_BAT);
	// 处理回应
	if(PORT_STU_READ != PortStu)
	{
		if(PORT_STU_BUSY == PortStu)
		{
			if(LangureStu == 1)
			{
				LangureStr = "Data read failed, The device is busy, please operate later!";
			}
			else
			{
				LangureStr = "数据读取失败，设备繁忙，请稍后操作!";
			}
            InsertText(ui->te_prin_bat, LangureStr, NORMAL_FONT_SIZE, APP_FONT_COLOR_WARNNING);
		}
		else if(PORT_STU_TIMEOUT == PortStu)
		{
			if(LangureStu == 1)
			{
				LangureStr = "Data read failed, The device timed out. Please check the device connection status and try again!";
			}
			else
			{
				LangureStr = "数据读取失败，设备超时，请检查设备连接状态后重试!";
			}
            InsertText(ui->te_prin_bat, LangureStr, NORMAL_FONT_SIZE, APP_FONT_COLOR_WARNNING);
		}
		else
		{
			if(LangureStu == 1)
			{
				LangureStr = "Data read failed!";
			}
			else
			{
				LangureStr = "数据读取失败!";
			}
            InsertText(ui->te_prin_bat, LangureStr, NORMAL_FONT_SIZE, APP_FONT_COLOR_FAILED);
		}
		return false;
	}
	// 解析回应数据-BatData
   // 电池型号
   uint16_t BatKind = 0;
   BatKind = BatData[1];
   switch(BatKind)
   {
   case BAT_KIND_5G:     ui->cbx_bat_model->setCurrentIndex(0); break;
   case BAT_KIND_5C:     ui->cbx_bat_model->setCurrentIndex(1); break;
   case BAT_KIND_5S:     ui->cbx_bat_model->setCurrentIndex(2); break;
   case BAT_KIND_5SE:    ui->cbx_bat_model->setCurrentIndex(3); break;
//   case BAT_KIND_SE:     ui->cbx_bat_model->setCurrentIndex(BatKind); break;
//   case BAT_KIND_SE2:    ui->cbx_bat_model->setCurrentIndex(BatKind); break;
   case BAT_KIND_SE3:    ui->cbx_bat_model->setCurrentIndex(4); break;
   case BAT_KIND_6G:     ui->cbx_bat_model->setCurrentIndex(5); break;
   case BAT_KIND_6Plus:  ui->cbx_bat_model->setCurrentIndex(6); break;
   case BAT_KIND_6S:     ui->cbx_bat_model->setCurrentIndex(7); break;
   case BAT_KIND_6SPlus: ui->cbx_bat_model->setCurrentIndex(8); break;
   case BAT_KIND_7G:     ui->cbx_bat_model->setCurrentIndex(9); break;
   case BAT_KIND_7Plus:  ui->cbx_bat_model->setCurrentIndex(10); break;
   case BAT_KIND_8G:     ui->cbx_bat_model->setCurrentIndex(11); break;
   case BAT_KIND_8Plus:  ui->cbx_bat_model->setCurrentIndex(12); break;
   case BAT_KIND_X:      ui->cbx_bat_model->setCurrentIndex(13); break;
   case BAT_KIND_XS:     ui->cbx_bat_model->setCurrentIndex(14); break;
   case BAT_KIND_XSM:    ui->cbx_bat_model->setCurrentIndex(15); break;
   case BAT_KIND_XR:     ui->cbx_bat_model->setCurrentIndex(16); break;
   case BAT_KIND_11G:    ui->cbx_bat_model->setCurrentIndex(17); break;
   case BAT_KIND_11Pro:  ui->cbx_bat_model->setCurrentIndex(18); break;
   case BAT_KIND_11PM:   ui->cbx_bat_model->setCurrentIndex(19); break;
   case BAT_KIND_12G:    ui->cbx_bat_model->setCurrentIndex(20); break;
//   case BAT_KIND_12Pro:  ui->cbx_bat_model->setCurrentIndex(BatKind); break;
   case BAT_KIND_12PM:   ui->cbx_bat_model->setCurrentIndex(21); break;
   case BAT_KIND_12MN:   ui->cbx_bat_model->setCurrentIndex(22); break;
   case BAT_KIND_13G:    ui->cbx_bat_model->setCurrentIndex(23); break;
   case BAT_KIND_13Pro:  ui->cbx_bat_model->setCurrentIndex(24); break;
   case BAT_KIND_13PM:   ui->cbx_bat_model->setCurrentIndex(25); break;
   case BAT_KIND_13MN:   ui->cbx_bat_model->setCurrentIndex(26); break;
   case BAT_KIND_14G:    ui->cbx_bat_model->setCurrentIndex(27); break;
//   case BAT_KIND_14Plus: ui->cbx_bat_model->setCurrentIndex(BatKind); break;
   case BAT_KIND_14Pro:  ui->cbx_bat_model->setCurrentIndex(28); break;
   case BAT_KIND_14PM:   ui->cbx_bat_model->setCurrentIndex(29); break;
   }
   // 设计容量
   uint16_t DesignCap = 0;
   DesignCap = ((BatData[2] << 8)&0xFF00) + (BatData[3]&0x00FF);
   ui->sb_DesignCAP->setValue(DesignCap);
   // 实际容量
   uint16_t FullChargeCap = 0;
   FullChargeCap = ((BatData[4] << 8)&0xFF00) + (BatData[5]&0x00FF);
   ui->sb_ActualCAP->setValue(FullChargeCap);
   // 循环次数
   uint16_t CycleCount = 0;
   CycleCount = ((BatData[6] << 8)&0xFF00) + (BatData[7]&0x00FF);
   ui->sb_LoopCount->setValue(CycleCount);
   // 健康度
   uint16_t StateOffHealth = 0;
   StateOffHealth = ((BatData[8] << 8)&0xFF00) + (BatData[9]&0x00FF);
   ui->sb_BatHeath->setValue(StateOffHealth);
   // 厂家编号
   QByteArray ManuName;
   ManuName.clear();
   ManuName.append(BatData.mid(10,32));
   ui->le_ManufacturerNo->setText(ManuName);
   // 序列号
   QByteArray BatSN;
   BatSN.clear();
   BatSN.append(BatData.mid(42,18));
   ui->le_SN->setText(BatSN);
   // 生产厂家
   //   "C01"-苏州顺达
   if(BatSN.mid(0,3) == "C01")
   {
       if(LangureStu == 1)
       {
           ui->le_Mfrs->setText("SHUNDA");
       }
       else
       {
           ui->le_Mfrs->setText("苏州顺达");
       }
   }
   //   "F8Y"-深圳欣旺达
   else if(BatSN.mid(0,3) == "F8Y")
   {
       if(LangureStu == 1)
       {
           ui->le_Mfrs->setText("SUNWODA");
       }
       else
       {
           ui->le_Mfrs->setText("深圳欣旺达");
       }
   }
   //   "F5D"-惠州德赛
   else if(BatSN.mid(0,3) == "F5D")
   {
       if(LangureStu == 1)
       {
           ui->le_Mfrs->setText("DESAY");
       }
       else
       {
           ui->le_Mfrs->setText("惠州德赛");
       }
   }
   //   "FG9"-常熟华普
   else if(BatSN.mid(0,3) == "FG9")
   {
       if(LangureStu == 1)
       {
           ui->le_Mfrs->setText("HUAPU");
       }
       else
       {
           ui->le_Mfrs->setText("常熟华普");
       }
   }
   //   "D86"-常熟新世
   else if(BatSN.mid(0,3) == "D86")
   {
       if(LangureStu == 1)
       {
           ui->le_Mfrs->setText("XINSHI");
       }
       else
       {
            ui->le_Mfrs->setText("常熟新世");
       }
   }
   //   "YW2"-无锡索尼
   else if(BatSN.mid(0,3) == "YW2")
   {
       if(LangureStu == 1)
       {
           ui->le_Mfrs->setText("SONY");
       }
       else
       {
            ui->le_Mfrs->setText("无锡索尼");
       }
   }
   // 生产日期
   QByteArray BatDate;
   BatDate.clear();
   BatDate.append(BatData.mid(60,10));
   ui->le_PD->setText(BatDate);
   // 状态
   // 电量
   uint16_t RemainingCap = 0;
   RemainingCap = ((BatData[70] << 8)&0xFF00) + (BatData[71]&0x00FF);
   ui->lbl_Electricity_val->setText(QString::number(RemainingCap));
   // 电池温度
   uint16_t Temperature = 0;
   Temperature = ((BatData[72] << 8)&0xFF00) + (BatData[73]&0x00FF);
   ui->lbl_CellTemperature_val->setText(QString::number(Temperature));
   // 电池电压
   uint16_t Voltage = 0;
   Voltage = ((BatData[74] << 8)&0xFF00) + (BatData[75]&0x00FF);
   ui->lbl_VBATT_val->setText(QString::number(Voltage));
   // 电池电流
   uint16_t AverageCurrent = 0;
   AverageCurrent = ((BatData[76] << 8)&0xFF00) + (BatData[77]&0x00FF);
   ui->lbl_BatteryCurrent_val->setText(QString::number(AverageCurrent));

   LangureStr_Init_ReadData_Succeed(ui->te_prin_bat);
   LastPortStu = PORT_STU_FREE;
   PortStu = PORT_STU_FREE;
	return true;
}
// F210电池修复-写数据
bool MainWindow::Write_Bat_Data_to_F210()
{
	// 发送写入电池数据包
    QByteArray LineStr;
    LineStr.clear();
    LineStr.resize(10);
    /*组包*/
    // 电池型号
    uint16_t BatKind = ui->cbx_bat_model->currentIndex();
    switch(BatKind)
    {
    case 0: BatKind = BAT_KIND_5G;     break;
    case 1: BatKind = BAT_KIND_5C;     break;
    case 2: BatKind = BAT_KIND_5S;     break;
    case 3: BatKind = BAT_KIND_5SE;    break;
 //   case BAT_KIND_SE:     ui->cbx_bat_model->setCurrentIndex(BatKind); break;
 //   case BAT_KIND_SE2:    ui->cbx_bat_model->setCurrentIndex(BatKind); break;
    case 4: BatKind = BAT_KIND_SE3;    break;
    case 5: BatKind = BAT_KIND_6G;     break;
    case 6: BatKind = BAT_KIND_6Plus;  break;
    case 7: BatKind = BAT_KIND_6S;     break;
    case 8: BatKind = BAT_KIND_6SPlus; break;
    case 9: BatKind = BAT_KIND_7G;     break;
    case 10:BatKind = BAT_KIND_7Plus;  break;
    case 11:BatKind = BAT_KIND_8G;     break;
    case 12:BatKind = BAT_KIND_8Plus;  break;
    case 13:BatKind = BAT_KIND_X;      break;
    case 14:BatKind = BAT_KIND_XS;     break;
    case 15:BatKind = BAT_KIND_XSM;    break;
    case 16:BatKind = BAT_KIND_XR;     break;
    case 17:BatKind = BAT_KIND_11G;    break;
    case 18:BatKind = BAT_KIND_11Pro;  break;
    case 19:BatKind = BAT_KIND_11PM;   break;
    case 20:BatKind = BAT_KIND_12G;    break;
 //   case BAT_KIND_12Pro:  ui->cbx_bat_model->setCurrentIndex(BatKind); break;
    case 21:BatKind = BAT_KIND_12PM;   break;
    case 22:BatKind = BAT_KIND_12MN;   break;
    case 23:BatKind = BAT_KIND_13G;    break;
    case 24:BatKind = BAT_KIND_13Pro;  break;
    case 25:BatKind = BAT_KIND_13PM;   break;
    case 26:BatKind = BAT_KIND_13MN;   break;
    case 27:BatKind = BAT_KIND_14G;    break;
 //   case BAT_KIND_14Plus: ui->cbx_bat_model->setCurrentIndex(BatKind); break;
    case 28:BatKind = BAT_KIND_14Pro;  break;
    case 29:BatKind = BAT_KIND_14PM;   break;
    }
    LineStr[0] = (BatKind >> 8) & 0xFF;
    LineStr[1] = (BatKind >> 0) & 0xFF;
    // 设计容量
    uint16_t DesignCap = ui->sb_DesignCAP->value();
    LineStr[2] = (DesignCap >> 8) & 0xFF;
    LineStr[3] = (DesignCap >> 0) & 0xFF;
    // 实际容量
    uint16_t FullChargeCap = ui->sb_ActualCAP->value();
    LineStr[4] = (FullChargeCap >> 8) & 0xFF;
    LineStr[5] = (FullChargeCap >> 0) & 0xFF;
    // 循环次数
    uint16_t CycleCount = ui->sb_LoopCount->value();
    LineStr[6] = (CycleCount >> 8) & 0xFF;
    LineStr[7] = (CycleCount >> 0) & 0xFF;
    // 健康度
    uint16_t StateOffHealth = ui->sb_BatHeath->value();
    LineStr[8] = (StateOffHealth >> 8) & 0xFF;
    LineStr[9] = (StateOffHealth >> 0) & 0xFF;
    // 厂家编号
    QByteArray ManuName = ui->le_ManufacturerNo->text().toUtf8();
    int StrLen = 32;
    if(ManuName.size() >= StrLen)
    {
        LineStr.append(ManuName.mid(0,StrLen));
    }
    else
    {
        LineStr.append(ManuName);
        QByteArray SpaceBuff;
        SpaceBuff.clear();
        SpaceBuff.resize(StrLen);
        for (int i=0;i<StrLen-ManuName.size();i++)
        {
            SpaceBuff[i] = 0x00;
        }
        LineStr.append(SpaceBuff, StrLen-ManuName.size());
    }
    // 序列号
    QByteArray BatSN = ui->le_SN->text().toUtf8();
    StrLen = 18;
    if(BatSN.size() >= StrLen)
    {
        LineStr.append(BatSN.mid(0,StrLen));
    }
    else
    {
        LineStr.append(BatSN);
        QByteArray SpaceBuff;
        SpaceBuff.clear();
        SpaceBuff.resize(StrLen);
        for (int i=0;i<StrLen-BatSN.size();i++)
        {
            SpaceBuff[i] = 0x00;
        }
        LineStr.append(SpaceBuff, StrLen-BatSN.size());
    }
    // 生产日期
    QByteArray BatDate = ui->le_PD->text().toUtf8();
    StrLen = 10;
    if(BatDate.size() >= StrLen)
    {
        LineStr.append(BatDate.mid(0,StrLen));
    }
    else
    {
        LineStr.append(BatDate);
        QByteArray SpaceBuff;
        SpaceBuff.clear();
        SpaceBuff.resize(StrLen);
        for (int i=0;i<StrLen-BatDate.size();i++)
        {
            SpaceBuff[i] = 0x00;
        }
        LineStr.append(SpaceBuff, StrLen-BatDate.size());
    }
    // 状态
    // 电量
    uint16_t RemainingCap = ui->lbl_Electricity_val->text().toInt();
    LineStr.append((RemainingCap >> 8) & 0xFF);
    LineStr.append((RemainingCap >> 0) & 0xFF);
    // 电池温度
    uint16_t Temperature = ui->lbl_CellTemperature_val->text().toInt();
    LineStr.append((Temperature >> 8) & 0xFF);
    LineStr.append((Temperature >> 0) & 0xFF);
    // 电池电压
    uint16_t Voltage = ui->lbl_VBATT_val->text().toInt();
    LineStr.append((Voltage >> 8) & 0xFF);
    LineStr.append((Voltage >> 0) & 0xFF);
    // 电池电流
    uint16_t AverageCurrent = ui->lbl_BatteryCurrent_val->text().toInt();
    LineStr.append((AverageCurrent >> 8) & 0xFF);
    LineStr.append((AverageCurrent >> 0) & 0xFF);

    LastPortStu = PORT_STU_BURN;
    PortStu = PORT_STU_WAIT;
    Wait_TimeOut_to_Send_Three_Time(LineStr, PORT_STU_READ, SEND_BURN_DATA_BAT);
    // 处理回应
    if(PORT_STU_READ != PortStu)
    {
        if(PORT_STU_BUSY == PortStu)
        {
            if(LangureStu == 1)
            {
                LangureStr = "Data write failed, The device is busy, please operate later!";
            }
            else
            {
                LangureStr = "数据写入失败，设备繁忙，请稍后操作!";
            }
            InsertText(ui->te_prin_bat, LangureStr, NORMAL_FONT_SIZE, APP_FONT_COLOR_WARNNING);
        }
        else if(PORT_STU_TIMEOUT == PortStu)
        {
            if(LangureStu == 1)
            {
                LangureStr = "Data write failed, The device timed out. Please check the device connection status and try again!";
            }
            else
            {
                LangureStr = "数据写入失败，设备超时，请检查设备连接状态后重试!";
            }
            InsertText(ui->te_prin_bat, LangureStr, NORMAL_FONT_SIZE, APP_FONT_COLOR_WARNNING);
        }
        else
        {
            if(LangureStu == 1)
            {
                LangureStr = "Data write failed!";
            }
            else
            {
                LangureStr = "数据写入失败!";
            }
            InsertText(ui->te_prin_bat, LangureStr, NORMAL_FONT_SIZE, APP_FONT_COLOR_FAILED);
        }
        return false;
    }
    {
        // 解析回应数据-BatData
        // 电池型号
       uint16_t BatKind = 0;
       BatKind = BatData[1];
       switch(BatKind)
       {
       case BAT_KIND_5G:     ui->cbx_bat_model->setCurrentIndex(0); break;
       case BAT_KIND_5C:     ui->cbx_bat_model->setCurrentIndex(1); break;
       case BAT_KIND_5S:     ui->cbx_bat_model->setCurrentIndex(2); break;
       case BAT_KIND_5SE:    ui->cbx_bat_model->setCurrentIndex(3); break;
    //   case BAT_KIND_SE:     ui->cbx_bat_model->setCurrentIndex(BatKind); break;
    //   case BAT_KIND_SE2:    ui->cbx_bat_model->setCurrentIndex(BatKind); break;
       case BAT_KIND_SE3:    ui->cbx_bat_model->setCurrentIndex(4); break;
       case BAT_KIND_6G:     ui->cbx_bat_model->setCurrentIndex(5); break;
       case BAT_KIND_6Plus:  ui->cbx_bat_model->setCurrentIndex(6); break;
       case BAT_KIND_6S:     ui->cbx_bat_model->setCurrentIndex(7); break;
       case BAT_KIND_6SPlus: ui->cbx_bat_model->setCurrentIndex(8); break;
       case BAT_KIND_7G:     ui->cbx_bat_model->setCurrentIndex(9); break;
       case BAT_KIND_7Plus:  ui->cbx_bat_model->setCurrentIndex(10); break;
       case BAT_KIND_8G:     ui->cbx_bat_model->setCurrentIndex(11); break;
       case BAT_KIND_8Plus:  ui->cbx_bat_model->setCurrentIndex(12); break;
       case BAT_KIND_X:      ui->cbx_bat_model->setCurrentIndex(13); break;
       case BAT_KIND_XS:     ui->cbx_bat_model->setCurrentIndex(14); break;
       case BAT_KIND_XSM:    ui->cbx_bat_model->setCurrentIndex(15); break;
       case BAT_KIND_XR:     ui->cbx_bat_model->setCurrentIndex(16); break;
       case BAT_KIND_11G:    ui->cbx_bat_model->setCurrentIndex(17); break;
       case BAT_KIND_11Pro:  ui->cbx_bat_model->setCurrentIndex(18); break;
       case BAT_KIND_11PM:   ui->cbx_bat_model->setCurrentIndex(19); break;
       case BAT_KIND_12G:    ui->cbx_bat_model->setCurrentIndex(20); break;
    //   case BAT_KIND_12Pro:  ui->cbx_bat_model->setCurrentIndex(BatKind); break;
       case BAT_KIND_12PM:   ui->cbx_bat_model->setCurrentIndex(21); break;
       case BAT_KIND_12MN:   ui->cbx_bat_model->setCurrentIndex(22); break;
       case BAT_KIND_13G:    ui->cbx_bat_model->setCurrentIndex(23); break;
       case BAT_KIND_13Pro:  ui->cbx_bat_model->setCurrentIndex(24); break;
       case BAT_KIND_13PM:   ui->cbx_bat_model->setCurrentIndex(25); break;
       case BAT_KIND_13MN:   ui->cbx_bat_model->setCurrentIndex(26); break;
       case BAT_KIND_14G:    ui->cbx_bat_model->setCurrentIndex(27); break;
    //   case BAT_KIND_14Plus: ui->cbx_bat_model->setCurrentIndex(BatKind); break;
       case BAT_KIND_14Pro:  ui->cbx_bat_model->setCurrentIndex(28); break;
       case BAT_KIND_14PM:   ui->cbx_bat_model->setCurrentIndex(29); break;
       }
       // 设计容量
       uint16_t DesignCap = 0;
       DesignCap = ((BatData[2] << 8)&0xFF00) + (BatData[3]&0x00FF);
       ui->sb_DesignCAP->setValue(DesignCap);
       // 实际容量
       uint16_t FullChargeCap = 0;
       FullChargeCap = ((BatData[4] << 8)&0xFF00) + (BatData[5]&0x00FF);
       ui->sb_ActualCAP->setValue(FullChargeCap);
       // 循环次数
       uint16_t CycleCount = 0;
       CycleCount = ((BatData[6] << 8)&0xFF00) + (BatData[7]&0x00FF);
       ui->sb_LoopCount->setValue(CycleCount);
       // 健康度
       uint16_t StateOffHealth = 0;
       StateOffHealth = ((BatData[8] << 8)&0xFF00) + (BatData[9]&0x00FF);
       ui->sb_BatHeath->setValue(StateOffHealth);
       // 厂家编号
       QByteArray ManuName;
       ManuName.clear();
       ManuName.append(BatData.mid(10,32));
       ui->le_ManufacturerNo->setText(ManuName);
       // 序列号
       QByteArray BatSN;
       BatSN.clear();
       BatSN.append(BatData.mid(42,18));
       ui->le_SN->setText(BatSN);
       // 生产厂家
       //   "C01"-苏州顺达
       if(BatSN.mid(0,3) == "C01")
       {
           if(LangureStu == 1)
           {
               ui->le_Mfrs->setText("SHUNDA");
           }
           else
           {
               ui->le_Mfrs->setText("苏州顺达");
           }
       }
       //   "F8Y"-深圳欣旺达
       else if(BatSN.mid(0,3) == "F8Y")
       {
           if(LangureStu == 1)
           {
               ui->le_Mfrs->setText("SUNWODA");
           }
           else
           {
               ui->le_Mfrs->setText("深圳欣旺达");
           }
       }
       //   "F5D"-惠州德赛
       else if(BatSN.mid(0,3) == "F5D")
       {
           if(LangureStu == 1)
           {
               ui->le_Mfrs->setText("DESAY");
           }
           else
           {
               ui->le_Mfrs->setText("惠州德赛");
           }
       }
       //   "FG9"-常熟华普
       else if(BatSN.mid(0,3) == "FG9")
       {
           if(LangureStu == 1)
           {
               ui->le_Mfrs->setText("HUAPU");
           }
           else
           {
               ui->le_Mfrs->setText("常熟华普");
           }
       }
       //   "D86"-常熟新世
       else if(BatSN.mid(0,3) == "D86")
       {
           if(LangureStu == 1)
           {
               ui->le_Mfrs->setText("XINSHI");
           }
           else
           {
                ui->le_Mfrs->setText("常熟新世");
           }
       }
       // 生产日期
       QByteArray BatDate;
       BatDate.clear();
       BatDate.append(BatData.mid(60,10));
       ui->le_PD->setText(BatDate);
       // 状态
       // 电量
       uint16_t RemainingCap = 0;
       RemainingCap = ((BatData[70] << 8)&0xFF00) + (BatData[71]&0x00FF);
       ui->lbl_Electricity_val->setText(QString::number(RemainingCap));
       // 电池温度
       uint16_t Temperature = 0;
       Temperature = ((BatData[72] << 8)&0xFF00) + (BatData[73]&0x00FF);
       ui->lbl_CellTemperature_val->setText(QString::number(Temperature));
       // 电池电压
       uint16_t Voltage = 0;
       Voltage = ((BatData[74] << 8)&0xFF00) + (BatData[75]&0x00FF);
       ui->lbl_VBATT_val->setText(QString::number(Voltage));
       // 电池电流
       uint16_t AverageCurrent = 0;
       AverageCurrent = ((BatData[76] << 8)&0xFF00) + (BatData[77]&0x00FF);
       ui->lbl_BatteryCurrent_val->setText(QString::number(AverageCurrent));
    }
    LangureStr_Init_BurnData_Succeed(ui->te_prin_bat);
	return true;
}

//取反
QByteArray getEncryptFile(QByteArray sCRCBuf,int iLen)
{
    QByteArray val0;

    //算法部分 0xff-0x%%
    for(int iCount = 0;iCount < iLen;iCount ++)
    {
        QString buf = sCRCBuf.mid(iCount,1).toHex();
        int num = 0xff - buf.toInt(0,16);

        val0.append((uchar)(num));
    }
    return val0;
}
//将字节序列转换为对应的16进制字符串
QString MainWindow::ByteArray2Hex(QByteArray data)
{
    QString ret(data.toHex().toUpper());
    int len = ret.length()/2;
    for(int i=1;i<len;i++)
    {
        ret.insert(2*i+i-1," ");
    }

    return ret;
}
//将字节序列转换为字符串
QString MainWindow::ByteArray2QString(QByteArray data,int size)
{
    QString ret;
    for(int i=0;i<size;i++)
    {
        ret += data.at(i);
    }

    return ret;
}
//将16进制字符串转换为对应的字节序列
QByteArray MainWindow::Hex2ByteArray(QString HexString)
{
    bool ok;
    QByteArray ret;
    HexString = HexString.trimmed();
    HexString = HexString.simplified();
    QStringList sl = HexString.split(" ");

    foreach (QString s, sl) {
        if(!s.isEmpty())
        {
            char c = s.toInt(&ok,16)&0xFF;
            if(ok){
                ret.append(c);
            }
        }
    }
    return ret;
}

//命令发送
void MainWindow::pc_to_mcu_send_data(QByteArray LineStr,int SendStu)
{
    QByteArray LineBuff = LineStr;
    QByteArray SendBuff;
    SendBuff.resize(PORT_SIZE_MAX_F210);
    int BuffCnt = 0;

    QByteArray RandNums;
    RandNums.resize(4);
    RandNums.clear();
    generateRandomNumber(RandNums, 4);
    for(int icnt=0;icnt<4;icnt++)
    {
        SendBuff[icnt] = RandNums.at(icnt);
    }
    BuffCnt += 4;
    int TempModel;
    TempModel = ModelStu;
    //id
    switch (SendStu) {
    case SEND_DATA_SYNC:
    {
        SendBuff[BuffCnt] = 0x00;
        SendBuff[BuffCnt+1] = 0x00;
        SendBuff[BuffCnt+2] = 0x00;
        SendBuff[BuffCnt+3] = 0x01;
        break;
    }
    case SEND_READ_MTSN_REQ:
    {
        SendBuff[BuffCnt] = 0xA1;
        SendBuff[BuffCnt+1] = 0x00;
        SendBuff[BuffCnt+2] = TempModel;
        SendBuff[BuffCnt+3] = 0x00;
        break;
    }
    case SEND_READ_REQ:
    {
        SendBuff[BuffCnt] = 0xA1;
        SendBuff[BuffCnt+1] = 0x00;
        SendBuff[BuffCnt+2] = TempModel;
        SendBuff[BuffCnt+3] = 0x01;
        break;
    }
    case SEND_BURN_MTSN_REQ:
    {
        SendBuff[BuffCnt] = 0xB1;
        SendBuff[BuffCnt+1] = 0x00;
        SendBuff[BuffCnt+2] = TempModel;
        SendBuff[BuffCnt+3] = 0x00;
        break;
    }
    case SEND_BURN_MTSN_DEV:
    {
        SendBuff[BuffCnt] = 0xB2;
        SendBuff[BuffCnt+1] = 0x00;
        SendBuff[BuffCnt+2] = TempModel;
        SendBuff[BuffCnt+3] = 0x00;
        break;
    }
    case SEND_BURN_DATA:
    {
        PageCnt++;
        SendBuff[BuffCnt] = 0xB1;
        SendBuff[BuffCnt+1] = (PageCnt&0x00FF);
        SendBuff[BuffCnt+2] = TempModel;
        SendBuff[BuffCnt+3] = 0x00;
        break;
    }
    case SEND_DATA_UPG:
    {
        PageCnt++;
        SendBuff[BuffCnt] = 0xC0;
        SendBuff[BuffCnt+1] = ((PageCnt>>8)&0x00FF);
        SendBuff[BuffCnt+2] = (PageCnt&0x00FF);
        SendBuff[BuffCnt+3] = 0x00;
        break;
    }
    case SEND_FPGA_UPG:
    {
        PageCnt++;
        SendBuff[BuffCnt] = 0xC1;
        SendBuff[BuffCnt+1] = ((PageCnt>>8)&0x00FF);
        SendBuff[BuffCnt+2] = (PageCnt&0x00FF);
        SendBuff[BuffCnt+3] = 0x00;
        break;
    }
    case SEND_DATA_DONE:
    {
        SendBuff[BuffCnt] = 0xC0;
        SendBuff[BuffCnt+1] = 0xFF;
        SendBuff[BuffCnt+2] = 0xFF;
        SendBuff[BuffCnt+3] = 0xFF;
        break;
    }
    case SEND_FPGA_DONE:
    {
        SendBuff[BuffCnt] = 0xC1;
        SendBuff[BuffCnt+1] = 0xFF;
        SendBuff[BuffCnt+2] = 0xFF;
        SendBuff[BuffCnt+3] = 0xFF;
        break;
    }
    case SEND_FILE_SIZE:
    {
        SendBuff[BuffCnt] = 0xC2;
        SendBuff[BuffCnt+1] = ((AllFileSize>>16)&0x00FF);
        SendBuff[BuffCnt+2] = ((AllFileSize>>8)&0x00FF);
        SendBuff[BuffCnt+3] = (AllFileSize&0x00FF);
        break;
    }
    case SEND_PORT_DISC:
    {
        SendBuff[BuffCnt] = 0xEE;
        SendBuff[BuffCnt+1] = 0xEE;
        SendBuff[BuffCnt+2] = 0xEE;
        SendBuff[BuffCnt+3] = 0xEE;
        break;
    }
    case SEND_READ_DATA_BAT:
    {
        SendBuff[BuffCnt] = 0x21;
        SendBuff[BuffCnt+1] = 0x00;
        SendBuff[BuffCnt+2] = 0x00;
        SendBuff[BuffCnt+3] = 0x00;
        break;
    }
    case SEND_BURN_DATA_BAT:
    {
        SendBuff[BuffCnt] = 0x22;
        SendBuff[BuffCnt+1] = 0x00;
        SendBuff[BuffCnt+2] = 0x00;
        SendBuff[BuffCnt+3] = 0x00;
        break;
    }
//    case SEND_DATA_REPT:
    default:
    {
        SendBuff[BuffCnt] = 0x00;
        SendBuff[BuffCnt+1] = 0x0A;
        SendBuff[BuffCnt+2] = 0x00;
        SendBuff[BuffCnt+3] = 0x00;
        break;
    }
    }
    BuffCnt += 4;
    //Length
    uint16_t Size;
    Size = LineStr.size();
    SendBuff[BuffCnt] = (Size >> 8) & 0x00FF;
    SendBuff[BuffCnt+1] = Size & 0x00FF;
    BuffCnt += 2;
    //check add
    uint16_t AddVal;
    AddVal = crc16_result(SendBuff, 4);
    BuffCnt += 2;
    // 数据
    int icnt;
    if(!LineStr.isEmpty())
    {
        for(icnt=0;icnt<LineStr.size();icnt++) {
            SendBuff[BuffCnt+icnt] = LineBuff.at(icnt);
        }
        BuffCnt += icnt;
        AddVal += crc16_result(SendBuff.mid(12,Size), Size);
    }
    SendBuff[10] = (AddVal >> 8) & 0x00FF;
    SendBuff[11] = AddVal & 0x00FF;
    int StrLen = 512 - LineStr.size();
    if(StrLen>0)
    {
        RandNums.resize(StrLen);
        RandNums.clear();
        generateRandomNumber(RandNums, StrLen);

        for(icnt=0;icnt<StrLen;icnt++) {
            SendBuff[BuffCnt+icnt] = RandNums.at(icnt);
        }
        // 20230210——1711 同步时，选择语言并下发给设备，避免默认进入中文界面
        if(SEND_DATA_SYNC == SendStu)
        {
            if(LangureStu == 1)
            {
                SendBuff[38] = 0x5A;
            }
            else
            {
                if(0x5A == SendBuff[38])
                {
                    SendBuff[38] = 0xA5;
                }
            }
        }
    }

    if(SendBuff.size() != PORT_SIZE_MAX_F210)
    {
        return;
    }

    SendData = SendBuff;
    PortSerial->write(SendBuff, PORT_SIZE_MAX_F210);
}

//重发指令
void MainWindow::Port_Serial_Cmd_Repeat()
{
    QByteArray LineStr;
    LineStr.clear();
    pc_to_mcu_send_data(LineStr, PORT_STU_REPT);
}

//数据接收:触发中断->延时后接收数据
void MainWindow::Port_Serial_Read_clicked()
{
    RecvTimer->start(TIMER_RECV_TIME_OUT);
}
void MainWindow::Port_Serial_Read_Data()
{
    RecvTimer->stop();
    RecvStu = false;
    QByteArray ReadBuff;
    //从接收缓冲区中读取数据
    ReadBuff = PortSerial->readAll();
    RecvStr.append(ReadBuff);
    QByteArray TmpBuff;
    if(RecvStr.size() >= PORT_SIZE_MAX_F210)
    {
        TmpBuff.clear();
        TmpBuff.append(RecvStr.left(PORT_SIZE_MAX_F210));
        ReadBuff.resize(PORT_SIZE_MAX_F210);
        ReadBuff.clear();
        ReadBuff = TmpBuff;

        //校验CRC，若不成功则发送重复请求
        uint16_t AddVal;
        uint16_t AddCheckVal;
        AddVal = crc16_result(ReadBuff.mid(0,4), 4);
        //取长度
        AddCheckVal = (((ReadBuff[9]&0x00FF)<<8) & 0xFF00) | (ReadBuff[8]&0x00FF);
        int len = AddCheckVal;
        if(0 != len)
        {
            if(PORT_SIZE_MAX_F210 < len)
            {
                RecvStu = true;
                RecvStr.clear();
                return;
            }
            AddVal += crc16_result(ReadBuff.mid(12,len), len);
        }
        AddCheckVal = ((ReadBuff[11]<<8) & 0xFF00) | (ReadBuff[10]&0x00FF);
        if(AddVal != AddCheckVal)
        {
            RecvStu = true;
            RecvStr.clear();
        }
        else
        {
            uint32_t CmdId;
            CmdId = ((ReadBuff[7] << 24)&0xFF000000) | ((ReadBuff[6] << 16)&0x00FF0000) | ((ReadBuff[5] << 8)&0x0000FF00) | ((ReadBuff[4] << 0)&0x000000FF);
            if(0xE0000000 == CmdId)
            {
                RecvData = ReadBuff.mid(12,len);
                if(len>0)
                {
                    LangureStr = tr("失败,%1.").arg(ByteArray2QString(RecvData,len));
                }
                else
                {
                    if(LangureStu == 1)
                    {
                        LangureStr = "Error,unknown error!";
                    }
                    else
                    {
                        LangureStr = "失败,未知错误!";
                    }
                }
                PortStu = PORT_STU_ERROR;
            }
            else if(ReadBuff[7].operator==(0x00))
            {
                if(0x000A0000 == CmdId) {
                    PortSerial->write(SendData, PORT_SIZE_MAX_F210);
                    WaitTimer->stop();
                    PortStu = PORT_STU_WAIT;
                    WaitTimer->start(TIMER_SYNC_TIME_OUT);
                }
                else if(0x000B0000 == CmdId)
                {
                    if(WaitTimer->isActive())
                    {
                        WaitTimer->start(TIMER_SYNC_TIME_OUT);
                        SendOutCnt = 0;
                    }
                    else if(SyncTimer->isActive())
                    {
                        SyncTimer->start(TIMER_SYNC_TIME_OUT);
                        TimeOutCnt = 0;
                    }

                }
                //同步：1.端口连接后，检测数据是否为同步，同步后设置为同步状态（仅可进行界面操作）
                //校验：2.检查当前路径下是否有版本文件，若没有则报错 无法校验，请将版本文件存放到程序目录
                //校验完成：3.同步后，mcu发送当前版本号给pc，若pc校验mcu版本落后，则升级版本，此时pc设置为校验通过状态（可进行功能性操作）
                else if(CmdId == CMD_MCU_PC_SYNC) {
                    if(PORT_STU_SYNC == PortStu)
                    {
                        //取版本
                        QString ReadData = ByteArray2QString(ReadBuff, 524);
                        DevVersion.resize(4);
                        DevVersion.clear();

                        //Year
                        TmpBuff[0] = ReadData.mid(19,1).toInt();
                        TmpBuff[1] = ReadData.mid(20,1).toInt();
                        TmpBuff[2] = ReadData.mid(21,1).toInt();
                        TmpBuff[3] = ReadData.mid(22,1).toInt();
                        DevVerDate.append((TmpBuff[0]<<4|TmpBuff[1]));
                        DevVerDate.append((TmpBuff[2]<<4|TmpBuff[3]));

                        //Month,一月Jan，二月Feb，三月Mar，四月Apr，五月May，六月Jun，七月Jul，八月Aug，九月Sept，十月Oct，十一月Nov，十二月Dec
                        bool ContainStu;
                        int icnt = 0;
                        while(icnt<12)
                        {
                            ContainStu = ReadData.contains(Months[icnt], Qt::CaseInsensitive);
                            icnt++;
                            if(ContainStu)
                            {
                                break;
                            }
                        }
                        DevVerDate.append(icnt);

                        //Data
                        TmpBuff[0] = ReadData.mid(16,1).toInt();
                        TmpBuff[1] = ReadData.mid(17,1).toInt();
                        DevVerDate.append((TmpBuff[0]<<4|TmpBuff[1]));

                        if(ReadData[38] == 'v')
                        {
                            DevVersion.append(ReadData.mid(38,6).toLatin1());
                        }
                        else
                        {
                            DevVersion.append(ReadData.mid(40,4).toLatin1());
                        }
                        //
                        VersFileName = UPG_FILE_NAME_APP3;
                        Get_Check_Version_From_File();
                        //
                        if(LangureStu == 1)
                        {
                            LangureStr = "Current equipment version number: ";
                        }
                        else
                        {
                            LangureStr = "当前设备版本号：";
                        }
                        ui->lbl_dev_ver->setText(LangureStr+DevVersion);

                        //
                        PortStu = PORT_STU_FREE;
                        if(LangureStu == 1)
                        {
                            LangureStr = "Device connected";
                        }
                        else
                        {
                            LangureStr = "设备已连接";
                        }
                        InsertText(ui->te_prin, LangureStr, 9, APP_FONT_COLOR_NORMAL);
                        InsertText(ui->te_prin_bat, LangureStr, 9, APP_FONT_COLOR_NORMAL);

                        //
                        if((BinVersion.size() - DevVersion.size()) <= 1)
                        {
                            if(BinVersion == DevVersion)
                            {
                                //标记同步完成状态
                                if(LangureStu == 1)
                                {
                                    LangureStr = "You can go to the official website or contact customer service to determine whether the assistant is the latest version";
                                }
                                else
                                {
                                    LangureStr = "可前往官方网站或联系客服确定助手是否为最新版本";
                                }
                                InsertText(ui->te_prin, LangureStr, 9, APP_FONT_COLOR_NORMAL);
                                InsertText(ui->te_prin_bat, LangureStr, 9, APP_FONT_COLOR_NORMAL);
                                UpgStu = 1;
                            }
                            else
                            {
                                if(BinVersion > DevVersion)
                                {
                                    LangureStr_Init_DevVers_Low(ui->te_prin, BinVersion);
                                    LangureStr_Init_DevVers_Low(ui->te_prin_bat, BinVersion);
                                    if(DevVersion < UPG_FILE_VERS_F210)
                                    {
                                        UpgStu = 2;
                                    }
                                    else
                                    {
                                        UpgStu = 1;
                                    }
                                }
                                else
                                {
                                    //pc端落后，提示升级
                                    LangureStr_Init_AppVers_Low(ui->te_prin);
                                    LangureStr_Init_AppVers_Low(ui->te_prin_bat);
                                    UpgStu = 0;
                                }
                            }

                            if(DevVersion > "v1.0.1")
                            {
                                //新协议
                                PortVer = 1;
                            }
                            else
                            {
                                //旧协议
                                PortVer = 0;
                            }
                        }
                        else if(BinVersion.size() > DevVersion.size())
                        {
                            //mcu版本落后
                            LangureStr_Init_DevVers_Low(ui->te_prin, BinVersion);
                            LangureStr_Init_DevVers_Low(ui->te_prin_bat, BinVersion);
                            UpgStu = 2;
                        }
                        else
                        {
                            //pc端落后，提示升级
                            LangureStr_Init_AppVers_Low(ui->te_prin);
                            LangureStr_Init_AppVers_Low(ui->te_prin_bat);
                            UpgStu = 0;
                        }
                        if(PORT_STU_NULL != PortStu)
                        {
                            Port_Function_Lock_Or_Unlock(DISP_BTN_UNLOCK_ALL);
                            SyncTimer->start(TIMER_SYNC_TIME_OUT);
                        }
                    }
                    //MCU返回盖板码
                    else if(PORT_STU_READ_MTSN == LastPortStu)
                    {
                        RecvStr.clear();
                        return;
                    }
                    else if(PORT_STU_READ == LastPortStu && len != 512)
                    {
                        RecvStr.clear();
                        return;
                    }
                    //操作后的同步帧
                    else if(PORT_STU_WAIT == PortStu)
                    {
                        if(1 == PortVer && PORT_STU_WAIT_OK == LastPortStu)
                        {
                            RecvStr.clear();
                            return;
                        }
                        else
                        {
                            PortStu = LastPortStu;
                        }
                    }
                }
                else {
                    if(PORT_STU_WAIT == PortStu)
                    {
                        if(3 == WaitOutCnt)
                        {
                            PortStu = LastPortStu;
                            WaitOutCnt = 0;
                        }
                        else
                        {
                            Port_Serial_Cmd_Repeat();
                            WaitOutCnt++;
                            RecvStr.clear();
                            WaitTimer->stop();
                            PortStu = PORT_STU_WAIT;
                            WaitTimer->start(TIMER_SYNC_TIME_OUT);
                            return;
                        }
                    }
                }
                RecvCnt = ((ReadBuff[6]<<8)&0x000000FF) | (ReadBuff[5]&0x0000FF00);
                RecvSize = len;
                for (int cnt=0;cnt<len;cnt++) {
                    RecvData.append(ReadBuff.at(12+cnt));
                }
            }
            else
            {
                //读取
                if((ReadBuff[7].operator==(0xA0)) && (ReadBuff[4].operator==(0x00)))
                {
                    RecvCnt = ((ReadBuff[6]<<8)&0x000000FF) | (ReadBuff[5]&0x0000FF00);
                    RecvSize = len;
                    for (int cnt=0;cnt<len;cnt++) {
                        RecvData.append(ReadBuff.at(12+cnt));
                    }
                    PortStu = LastPortStu;
                }
                //读取盖板码成功
                else if(CmdId == 0xA2000000)
                {
                    RecvMtSN.clear();
                    RecvMtSN.append(ReadBuff.mid(12,len));
                    PortStu = LastPortStu;
                }
                //设备读取完成
                else if(CmdId == 0xA3000000)
                {
                    PortStu = LastPortStu;
                }
                //设备写入完成
                else if(CmdId == 0xB3000000)
                {
                    PortStu = LastPortStu;
                }
                //设备接收升级数据完成
                else if(CmdId == 0xC3000000)
                {
                    PortStu = LastPortStu;
                }
                else if(CmdId == 0xC4000000)
                {
                    PortStu = LastPortStu;
                }
                else if(CmdId == 0x21000000)
                {
                    PortStu = LastPortStu;
                    BatData.clear();
                    for (int cnt=0;cnt<len;cnt++) {
                        BatData.append(ReadBuff.at(12+cnt));
                    }
                }
                else if(CmdId == 0x22000000)
                {
                    PortStu = LastPortStu;
                }
                else
                {
                    if(10 == WaitOutCnt)
                    {
                        PortStu = LastPortStu;
                        WaitOutCnt = 0;
                    }
                    else
                    {
                        WaitTimer->stop();
                        Port_Serial_Cmd_Repeat();
                        WaitOutCnt++;
                        RecvStr.clear();
                        WaitTimer->start(100);
                        return;
                    }
                }
            }
            WaitOutCnt = 0;
            RecvStr.clear();
        }
    }
    else if(PORT_STU_SYNC == PortStu)
    {
        RecvStu = true;
        RecvStr.clear();
    }
}

